﻿#include "protocol.h" 
#include "qt_log.h"
#include "crc16.h"
#include "dl_net_data.h"
#include "app_struct.h"
//#include "QMsgBridge.h"
#include "protocol_struct.h"

static bool decode_data(uint8_t* data,int  len,dl_protocol_data_t* netdata);
static int decode_frm_dl(uint8_t* buf,int  size,dl_protocol_data_t* netdata);

int decode_dl(dl_protocol_data_t* netdata);

/*****************************************************************************
Function name : decode_dl
Description: 分解通讯协议 --》协议中的数据区
Input: data ：数据缓存    len : 数据长度    iodata  :协议框架结构体
Return: NONE
******************************************************************************/
bool decode_data(uint8_t* data,int  len,dl_protocol_data_t* netdata)
{
    if (len < 5)        //数据长度小5
    {
        return false;
    }
    cmd_t* pcmd = (cmd_t*)data;
//    uint8_t* pdata = (uint8_t*)(pcmd+1);
    switch( pcmd->cmd )
    {
        case CMD_GET:    {
//            get_handel(pcmd,pdata,netdata);     //获取
        }break;

        case CMD_SET:    {
            //set_handel(pcmd,pdata,netdata);     //设置
        }break;

        case CMD_PUT:    {
            //put_handel(pcmd,pdata,netdata);     //升级/心跳/
        }break;
    }
    return true;
}

/*****************************************************************************
Function name : encode_dl
Description: 打包数据 ---》通讯协议
Input: cmd ：指令    cmdlen : 指令长度    data  :打包缓存   datalen 打包长度
Return: NONE
******************************************************************************/
int encode_dl(uint8_t* cmd, int* cmdlen, uint8_t* data, int datalen)
{
    /* ----------------------------------------------------------------
    *  | 格式 |  帧头  |   功能码   |   数据区   |  CRC16  |  帧尾  |
    *  ----------------------------------------------------------------
    *  | 类型 |  BYTE  |    BYTE    |    BYTE    |  BYTE   |  BYTE  |
    *  ----------------------------------------------------------------
    *  | 长度 |   4    |     4      |     N      |    2    |    4   |
    *  ----------------------------------------------------------------
    *  | 数据 | "~!@#" |                                   |"$%\r\n"|
    *  ----------------------------------------------------------------
    */

    const char* pFrmHead = DL_FRM_HEAD;
    const char* pFrmTail = DL_FRM_TAIL;
    unsigned int len = datalen;
    unsigned short crc = 0;

    *cmdlen = 0;
    if (NULL == cmd || datalen < 0)
    {
        return -1;
    }
    //帧头
    memcpy(cmd + (*cmdlen), pFrmHead, DL_FRM_HEAD_LEN);
    *cmdlen += 4;
    //数据长度
    memcpy(cmd + (*cmdlen), &datalen, 4);
    *cmdlen += 4;
    //数据区
    if (data != NULL)
    {
        memcpy(cmd + (*cmdlen), data, len);
    }
    *cmdlen += len;
    //校验码
    crc = CRC16((unsigned char*)(data+5), len-5);
    memcpy(cmd + (*cmdlen), &crc, 2);
    *cmdlen += DL_FRM_CRC_LEN;

    //帧尾
    memcpy(cmd + (*cmdlen), pFrmTail, 4);
    *cmdlen += DL_FRM_TAIL_LEN;

    return 0;
}

/*****************************************************************************
Function name : decode_frm_dl
Description: 分解通讯协议 框架 头--尾--校验
Input: buf ：数据缓存    size : 数据长度    netdata  :协议框架结构体
Return: NONE
******************************************************************************/
int decode_frm_dl(uint8_t* buf,int  size,dl_protocol_data_t* netdata)
{
    /* ----------------------------------------------------------------
    *  | 格式 |  帧头  |   功能码   |   数据区   |  CRC16  |  帧尾  |
    *  ----------------------------------------------------------------
    *  | 类型 |  BYTE  |    BYTE    |    BYTE    |  BYTE   |  BYTE  |
    *  ----------------------------------------------------------------
    *  | 长度 |   4    |     4      |     N      |    2    |    4   |
    *  ----------------------------------------------------------------
    *  | 数据 | "~!@#" |                                   |"$%\r\n"|
    *  ----------------------------------------------------------------
    */
    const char* pFrmHead = DL_FRM_HEAD;
    const char* pFrmTail = DL_FRM_TAIL;
    uint8_t* pCmdTail;
    uint8_t* pCur = buf;
    int i;
    int onepacketlen;
    unsigned short len, crc, crcOK;
    if (buf == NULL || size < DL_FRM_MIN_LEN)           //最小数据长度
    {
        return -1;
    }

    // 帧头查找
    for (i = 0; i < size - (DL_FRM_HEAD_LEN - 1); ++i)
    {
        if (!memcmp(pFrmHead, pCur, DL_FRM_HEAD_LEN))
        {
            break;  //帧头匹配成功
        }
        pCur++;
    }

    if (i == size - (DL_FRM_HEAD_LEN - 1))
    {
        return i;      //找到帧头在数据末尾
    }
    pCur += 4;          //帧头4个字节
    if (size - i < DL_FRM_MIN_LEN)
    {
        return i;     //找到帧头在数据末尾
    }

    len = *((unsigned int*)pCur);    //数据长度
    pCur+=4;
    onepacketlen = len + DL_FRM_SIDES_LEN;  //一组包数据长度
    if (size - i < onepacketlen)
    {
        return i;
    }

    pCmdTail = pCur + len + DL_FRM_CRC_LEN;      //指令尾
    //查找到帧尾
    if (memcmp(pFrmTail, pCmdTail, DL_FRM_TAIL_LEN))
    {
        return (i + DL_FRM_HEAD_LEN);   //帧尾匹配失败
    }


    memcpy(&crc, pCur + len, DL_FRM_CRC_LEN);
    uint8_t* pcrc = pCur + 5;
    crcOK = CRC16((unsigned char*)(pcrc), len-5);
    if (crc != crcOK)
    {
        return (i + onepacketlen);   //校验位数据匹配失败
    }

    decode_data(pCur,len,netdata);     //数据指令解析

    pCur += len;

    pCur += DL_FRM_CRC_LEN;

    pCur += DL_FRM_TAIL_LEN;

    return (pCur - buf);
}

/*****************************************************************************
Function name : decode_dl
Description: 分解通讯协议 --》》分包处理
Input: buf ：数据缓存    size : 数据长度    netdata  :协议框架结构体
Return: NONE
******************************************************************************/
int decode_dl(dl_protocol_data_t* netdata)
{
    int used = 0;
    int dataPos = netdata->cmdlen;
    uint8_t* buf = netdata->pcmd;
    while (1)
    {
        //分解协议数据
        int ret = decode_frm_dl(buf,dataPos,netdata);

        if (ret > 0)
        {
            used += ret;
            dataPos -= ret;
            buf += ret;
            if(dataPos<=0)
                break;
        }
        else
        {
            break;
        }
    }

    return used;
}



